package cn.com.bx.mpaas.mpaas;

import static com.mpaas.framework.adapter.api.MPFramework.getApplicationContext;

import android.app.Application;
import android.util.Log;
import android.os.Handler;
import android.os.Looper;

import androidx.annotation.NonNull;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;

import alipay.yunpushcore.rpc.ResultPbPB;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import com.mpaas.core.MP;
import com.mpaas.core.MPInitParam;
import com.mpaas.mps.adapter.api.MPPush;

/** MpaasPlugin */
public class MpaasPlugin implements FlutterPlugin, MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private MethodChannel channel;
  private EventChannel eventChannel;
  private static EventChannel.EventSink eventSink;
  private static String deviceToken = null; // 缓存 token
  
  // 后台执行器和主线程 Handler
  private final ExecutorService backgroundExecutor = Executors.newCachedThreadPool();
  private final Handler mainHandler = new Handler(Looper.getMainLooper());
  private static String TAG = "MpaasPlugin"; // 用于绑定用户 ID 的 token
  public static void setToken(String token) {
    deviceToken = token;
  }

  // 通用的异步执行方法
  private void executeAsync(Result result, String operationName, Supplier<ResultPbPB> operation) {
    backgroundExecutor.execute(() -> {
      try {
        ResultPbPB apiResult = operation.get();
        Log.d("MpaasPlugin", operationName + " " + (apiResult.success ? "成功" : ("错误：" + apiResult.code)));
        
        mainHandler.post(() -> {
          if (apiResult.success) {
            result.success(true);
          } else {
            result.error(apiResult.code, "Failed to " + operationName + ": " + apiResult.code, null);
          }
        });
      } catch (Exception e) {
        Log.e("MpaasPlugin", "Error in " + operationName, e);
        mainHandler.post(() -> result.error("EXCEPTION", "Exception while " + operationName + ": " + e.getMessage(), null));
      }
    });
  }

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "mpaas");
    channel.setMethodCallHandler(this);

    MP.init(
      (Application) flutterPluginBinding.getApplicationContext(),
      MPInitParam.obtain().setCallback(new MPInitParam.MPCallback() {
        @Override
        public void onInit() {
          Log.d(TAG, "mPaaS Init finish");

          // 初始化消息推送
          MPPush.init(flutterPluginBinding.getApplicationContext());
          Log.d(TAG, "MPPush Init finish");
        }
      })
    );
  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
      switch (call.method) {
          case "getPlatformVersion":
              result.success("Android " + android.os.Build.VERSION.RELEASE);
              break;
          case "getToken":
              result.success(deviceToken);
              break;
          case "pushBindUserId":
              String userId = call.argument("userId");
              if (userId == null || userId.isEmpty()) {
                  result.error("INVALID_ARGUMENT", "User ID cannot be null or empty", null);
                  return;
              }

              executeAsync(result, "绑定 userId", () -> MPPush.bind(getApplicationContext(), userId, deviceToken));
              break;
          case "pushUnbindUserId":
              String unbindUserId = call.argument("userId");
              if (unbindUserId == null || unbindUserId.isEmpty()) {
                  result.error("INVALID_ARGUMENT", "User ID cannot be null or empty", null);
                  return;
              }

              executeAsync(result, "解绑 userId", () -> MPPush.unbind(getApplicationContext(), unbindUserId, deviceToken));
              break;
          case "pushBindUserIdWithPhone":
              String bindUserId = call.argument("userId");
              String phoneNumber = call.argument("phoneNumber");
              
              if (bindUserId == null || bindUserId.isEmpty()) {
                  result.error("INVALID_ARGUMENT", "User ID cannot be null or empty", null);
                  return;
              }
              
              if (phoneNumber == null || phoneNumber.isEmpty()) {
                  result.error("INVALID_ARGUMENT", "Phone number cannot be null or empty", null);
                  return;
              }

              executeAsync(result, "绑定 userId 和手机号", () -> MPPush.bind(getApplicationContext(), bindUserId, deviceToken, phoneNumber));
              break;
          default:
              result.notImplemented();
              break;
      }
  }


//         // 绑定用户 ID。
//         // 此用户 ID 由开发者自定义，既可以是真实用户系统的用户标识，也可以是能和每个用户形成映射关系的其他参数，例如账号、手机号等。
//         String userId = "自定义 userId";
//         ResultPbPB bindResult = MPPush.bind(getApplicationContext(), userId, token);
//         Log.d(TAG,"绑定 userId " + (bindResult.success ? "成功" : ("错误：" + bindResult.code)));

//         // 如需解绑用户 ID，例如用户退出登录，可调用：
// //        ResultPbPB unbindResult = MPPush.unbind(getApplicationContext(), userId, token);

  //         // （可选）绑定用户手机号。
//         // 在收到 token 后，还可以将 token 和用户的手机号码绑定，同时将 token 与用户 ID 和手机号绑定。绑定手机号码后，用户就可以通过该手机号码收到相关推送短信。
//         String phoneNumber = "138xxxxxxxx";
//         ResultPbPB bindPhoneResult = MPPush.bind(getApplicationContext(), userId, token,phoneNumber);
//         Log.d(TAG,"绑定 userId " + (bindPhoneResult.success ? "成功" : ("错误：" + bindPhoneResult.code)));

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
    if (eventChannel != null) {
      eventChannel.setStreamHandler(null);
    }
    // 关闭后台执行器
    if (backgroundExecutor != null && !backgroundExecutor.isShutdown()) {
      backgroundExecutor.shutdown();
    }
  }
}
